# -*- coding: utf-8 -*-
#
# The Philatelist program is a fork of the OpenNumismat program
# Copyright (c) 2011 - 2024 Vitaly Ignatov (OpenNumismat) <opennumismat@gmail.com>
# Copyright (c) 2021 - 2024 Victor Nabatov (Philatelist) <nabatov.victor@gmail.com>
#

import re

from PySide6.QtCore import Qt
from PySide6.QtGui import QDoubleValidator
from PySide6.QtWidgets import (
    QApplication, QBoxLayout, QDialog, QHBoxLayout, QLabel,
    QPushButton, QSizePolicy, QTabWidget, QVBoxLayout, QWidget
)
from Philatelist.StampEditor.FormItems import DoubleValidator
from Philatelist.StampEditor.BaseFormLayout import BaseFormLayout, BaseFormGroupBox, DesignFormLayout, ImageFormLayout
from Philatelist.StampEditor.FormItem import FormItem
from Philatelist.Collection.CollectionFields import FieldTypes as Type, ImagesFields, TitleTemplateFields
from Philatelist.Tools.Converters import stringToMoney
from Philatelist.TagsDialog import TagsDialog, TagsTreeWidget


class DetailsTabWidget(QTabWidget):

    Stretch = 'stretch item'

    def __init__(self, model, direction, parent=None):
        super().__init__(parent)
        self.direction = direction
        self.model = model
        self.reference = model.reference
        self.settings = model.settings
        self.tags_item = None
        self.createItems()
        self.createPages()

    def createPages(self):
        self.createStampPage()
        self.createDesignPage()
        self.createTraitsPage()
        self.createMarketPage()
        self.createOtherPage()

    def createStampPage(self):
        self.addTabPage(
            QApplication.translate('DetailsTabWidget', "Stamp"),
            [
                self.mainDetailsLayout(),
                self.catalogueLayout(),
                self.issueLayout(),
                self.Stretch,
                self.parametersLayout(),
                self.stateLayout(),
                self.urlLayout()
            ]
        )

    def createMarketPage(self):
        self.addTabPage(
            QApplication.translate('DetailsTabWidget', "Market"),
            []
        )

    def createDesignPage(self):
        self.addTabPage(
            QApplication.translate('DetailsTabWidget', "Design"),
            [
                self.stampLayout(),
                self.Stretch,
                self.reverseLayout(),
                self.varietyLayout()
            ]
        )

    def _layoutToWidget(self, layout):
        widget = QWidget(self)
        widget.setLayout(layout)
        widget.setStyleSheet('QGroupBox  {color: red;}')
        return widget

    def createTabPage(self, parts):
        # Remove all empty parts
        for part in parts:
            if isinstance(part, BaseFormGroupBox):
                if part.isEmpty():
                    parts.remove(part)

        if self.direction == QBoxLayout.LeftToRight:
            newParts = []
            layout = QVBoxLayout()
            stretchNeeded = True
            count = 0
            for part in parts:
                if part == self.Stretch:
                    if count > 0:
                        newParts.append(layout)
                        if stretchNeeded:
                            layout.insertStretch(-1)

                        layout = QVBoxLayout()

                    stretchNeeded = True
                    count = 0
                else:
                    if isinstance(part, QWidget):
                        layout.addWidget(part)
                        if part.sizePolicy().verticalPolicy() in (QSizePolicy.Preferred, QSizePolicy.Expanding):
                            stretchNeeded = False
                    else:
                        layout.addLayout(part)

                    count += 1

            if count > 0:
                newParts.append(layout)
                if stretchNeeded:
                    layout.insertStretch(-1)

            parts = newParts
        else:
            for part in parts:
                if part == self.Stretch:
                    parts.remove(part)

        pageLayout = QBoxLayout(self.direction, self)
        # Fill layout with it's parts
        stretchNeeded = True
        for part in parts:
            if isinstance(part, QWidget):
                pageLayout.addWidget(part)
                if part.sizePolicy().verticalPolicy() in (QSizePolicy.Preferred, QSizePolicy.Expanding):
                    stretchNeeded = False
            else:
                pageLayout.addLayout(part)
                if isinstance(part, ImageFormLayout):
                    stretchNeeded = False

        if self.direction == QBoxLayout.TopToBottom and stretchNeeded:
            pageLayout.insertStretch(-1)

        return self._layoutToWidget(pageLayout)

    def addTabPage(self, title, parts):
        page = self.createTabPage(parts)
        self.addTab(page, title)

    def addItem(self, field):
        # Skip image fields
        if field.type in Type.ImageTypes:
            return

        item = FormItem(
            self.settings,
            field.name,
            field.title,
            field.type | Type.Disabled,
            reference=self.reference
        )
        if not field.enabled:
            item.setHidden()

        self.items[field.name] = item

    def createItems(self):
        self.items = {}
        fields = self.model.fields
        for field in fields:
            if field not in fields.systemFields:
                self.addItem(field)

    def fillItems(self, record):
        if not record.isEmpty():
            # Fields with commission dependent on status field and should be filled after it and in right order
            ordered_item_keys = (
                'status', 'pay_price', 'total_pay_price', 'sale_price',
                'total_sale_price', 'region', 'country'
            )
            for key in ordered_item_keys:
                if key in self.items:
                    item = self.items[key]
                    self._fillItem(record, item)

            for item in self.items.values():
                if item.field() in ordered_item_keys:
                    continue

                self._fillItem(record, item)

            if self.tags_item:
                self.tags_item.fill(record)

    def _fillItem(self, record, item):
        if not record.isNull(item.field()):
            value = record.value(item.field())
            item.setValue(value)
        else:
            item.widget().clear()

    def clear(self):
        for item in self.items.values():
            item.widget().clear()

    def mainDetailsLayout(self):
        layout = BaseFormGroupBox(QApplication.translate('DetailsTabWidget', "Main details"))
        layout.addRow(self.items['region'], self.items['country'])
        layout.addRow(self.items['title'])
        layout.addHalfRow(self.items['denomination'])
        layout.addRow(self.items['year'], self.items['stamp_year'])
        layout.addRow(self.items['series'])
        layout.addRow(self.items['theme'])
        layout.addRow(self.items['type'], self.items['format'])
        return layout

    def stateLayout(self):
        layout = BaseFormGroupBox(QApplication.translate('DetailsTabWidget', "State"))
        layout.addRow(self.items['status'], self.items['quantity'])
        self.items['status'].widget().currentIndexChanged.connect(self.indexChangedState)
        layout.addRow(self.items['cancellation'])
        layout.addRow(self.items['grade'], self.items['condition'])
        layout.addRow(self.items['certificate'])
        layout.addRow(self.items['expert'], self.items['expertise_date'])
        layout.addRow(self.items['rating'])
        return layout

    def payLayout(self):
        layout = BaseFormGroupBox(QApplication.translate('DetailsTabWidget', "Purchase"))
        layout.addRow(self.items['pay_date'], self.items['pay_price'])
        # Add auxiliary field
        if self.items['pay_price'].hidden or self.items['total_pay_price'].hidden:
            item = None
        else:
            item = self.addPayCommission()

        layout.addRow(self.items['total_pay_price'], item)
        layout.addRow(self.items['seller'])
        layout.addRow(self.items['pay_place'])
        layout.addRow(self.items['buying_invoice'])
        layout.addRow(self.items['pay_info'])
        return layout

    def saleLayout(self):
        layout = BaseFormGroupBox(QApplication.translate('DetailsTabWidget', "Sale"))
        layout.addRow(self.items['sale_date'], self.items['sale_price'])
        # Add auxiliary field
        if self.items['sale_price'].hidden or self.items['total_sale_price'].hidden:
            item = None
        else:
            item = self.addSaleCommission()

        layout.addRow(self.items['total_sale_price'], item)
        layout.addRow(self.items['buyer'])
        layout.addRow(self.items['sale_place'])
        layout.addRow(self.items['sale_invoice'])
        layout.addRow(self.items['sale_info'])
        return layout

    def parametersLayout(self):
        layout = BaseFormGroupBox(QApplication.translate('DetailsTabWidget', "Parameters"))
        layout.addRow(self.items['material'], self.items['material_type'])
        layout.addRow(self.items['thickness'], self.items['printing'])
        layout.addRow(self.items['perforation'], self.items['perforation_size'])
        layout.addRow(self.items['full_size'], self.items['picture_size'])
        return layout

    def issueLayout(self):
        layout = BaseFormGroupBox(QApplication.translate('DetailsTabWidget', "Issue"))
        layout.addRow(self.items['issue_date'])
        layout.addRow(self.items['emission_period'])
        layout.addRow(self.items[ 'withdrawal'], self.items['circulation'])
        return layout

    def catalogueLayout(self):
        layout = BaseFormGroupBox(QApplication.translate('DetailsTabWidget', "Catalogue"))
        layout.layout.columnCount = 4
        layout.addRow(self.items['catalognum1'], self.items['catalognum2'])
        layout.addRow(self.items['catalognum3'], self.items['catalognum4'])
        return layout

    def pricesLayout(self):
        layout = BaseFormGroupBox(QApplication.translate('DetailsTabWidget', "Prices"))
        layout.addRow(self.items['price1'], self.items['price4'])
        layout.addRow(self.items['price2'], self.items['price5'])
        layout.addRow(self.items['price3'], self.items['price6'])
        layout.addHalfRow(self.items['currency'])
        return layout

    def urlLayout(self):
        layout = BaseFormLayout()
        layout.setAlignment(Qt.AlignTop)
        layout.addRow(self.items['url'])
        return layout

    def featuresLayout(self):
        layout = BaseFormGroupBox(QApplication.translate('DetailsTabWidget', "Features"))
        layout.addRow(self.items['features'])
        return layout

    def _createMarketParts(self, status):
        self.payCommission = None
        self.saleCommission = None
        pageParts = []
        pageParts.append(self.pricesLayout())
        if status in ('owned', 'ordered', 'sale', 'duplicate', 'exchange', 'rarity', 'variety'):
            pageParts.extend([self.payLayout()])

        elif status == 'sold':
            pageParts.extend([self.payLayout(), self.Stretch, self.saleLayout()])
        else:
            # Stamp Status is demo or wish or ordered so Market is empty
            layout = QHBoxLayout()
            layout.addWidget(
                QLabel(
                    QApplication.translate(
                        'DetailsTabWidget',
                        "Nothing to show. Change the stamp status."
                    )
                )
            )
            pageParts.append(layout)

        return pageParts

    def indexChangedState(self, index):
        pageIndex = self.currentIndex()
        self.removeTab(3)
        status = self.items['status'].widget().currentData()
        pageParts = self._createMarketParts(status)
        self.insertTab(
            3,
            self.createTabPage(pageParts),
            QApplication.translate('DetailsTabWidget', "Market")
        )
        self.setCurrentIndex(pageIndex)

    def addPayCommission(self):
        title = QApplication.translate('DetailsTabWidget', "Commission")
        item = FormItem(self.settings, None, title, Type.Money | Type.Disabled)
        self.payCommission = item.widget()
        self.items['pay_price'].widget().textChanged.connect(self.payPriceChanged)
        self.items['total_pay_price'].widget().textChanged.connect(self.payPriceChanged)
        return item

    def payPriceChanged(self, text):
        if self.payCommission:
            totalPriceValue = self.items['total_pay_price'].value()
            if totalPriceValue:
                price = textToFloat(self.items['pay_price'].value())
                totalPrice = textToFloat(totalPriceValue)
                self.payCommission.setText(floatToText(totalPrice - price))
            else:
                self.payCommission.setText('')

    def addSaleCommission(self):
        title = QApplication.translate('DetailsTabWidget', "Commission")
        item = FormItem(self.settings, None, title, Type.Money | Type.Disabled)
        self.saleCommission = item.widget()
        self.items['sale_price'].widget().textChanged.connect(self.salePriceChanged)
        self.items['total_sale_price'].widget().textChanged.connect(self.salePriceChanged)
        return item

    def salePriceChanged(self, text):
        if self.saleCommission:
            totalPriceValue = self.items['total_sale_price'].value()
            if totalPriceValue:
                price = textToFloat(self.items['sale_price'].value())
                totalPrice = textToFloat(totalPriceValue)
                self.saleCommission.setText(floatToText(price - totalPrice))
            else:
                self.saleCommission.setText('')

    def stampLayout(self):
        layout = BaseFormGroupBox(QApplication.translate('DetailsTabWidget', "Obverse design"))
        layout.addRow(self.items['stamp_design'])
        layout.addRow(self.items['stamp_color1'], self.items['stamp_color2'])
        layout.addRow(self.items['designer'], self.items['engraver'])
        return layout

    def reverseLayout(self):
        layout = BaseFormGroupBox(QApplication.translate('DetailsTabWidget', "Gumming"))
        layout.addRow(self.items['glue'], self.items['glue_color'])
        layout.addRow(self.items['stamp_reverse'])
        return layout

    def varietyLayout(self):
        layout = BaseFormGroupBox(QApplication.translate('DetailsTabWidget', "Variety"))
        layout.addRow(self.items['variety'])
        layout.addRow(self.items['variety_desc'])
        return layout

    def watermarkLayout(self):
        layout = BaseFormGroupBox(QApplication.translate('DetailsTabWidget', "Watermark"))
        layout.addRow(self.items['watermark'])
        return layout

    def gridLayout(self):
        layout = BaseFormGroupBox(QApplication.translate('DetailsTabWidget', "Grid"))
        layout.addRow(self.items['grid'])
        return layout

    def honeycombLayout(self):
        layout = BaseFormGroupBox(QApplication.translate('DetailsTabWidget', "Honeycomb"))
        layout.addRow(self.items['honeycomb'])
        return layout

    def rasterLayout(self):
        layout = BaseFormGroupBox(QApplication.translate('DetailsTabWidget', "Raster"))
        layout.addRow(self.items['raster'])
        return layout

    def createTraitsPage(self):
        self.addTabPage(
            QApplication.translate('DetailsTabWidget', "Traits"),
            [
                self.watermarkLayout(),
                self.gridLayout(),
                self.honeycombLayout(),
                self.rasterLayout(),
                self.Stretch,
                self.featuresLayout()
            ]
        )

    def otherLayout(self):
        layout = BaseFormLayout()
        layout.addRow(self.items['notes'])
        return layout

    def tagsLayout(self):
        self.tags_item = TagsTreeWidget(self.model.database(), True, self)
        return self.tags_item

    def createOtherPage(self):
        if self.settings['tags_used']:
            label = QLabel(self.tr("Tags"))
            label.setAlignment(Qt.AlignCenter)
            label.setStyleSheet("color: blue")
            self.addTabPage(
                QApplication.translate('DetailsTabWidget', "Notes"),
                [
                    self.otherLayout(),
                    label,
                    self.tagsLayout()
                ]
            )
        else:
            self.addTabPage(QApplication.translate('DetailsTabWidget', "Notes"), [self.otherLayout()])


class FormDetailsTabWidget(DetailsTabWidget):

    def __init__(self, model, parent=None, usedFields=None):
        self.usedFields = usedFields
        super().__init__(model, QBoxLayout.TopToBottom, parent)

    def createPages(self):
        self.oldStatus = 'demo'
        self.createStampPage()
        self.createDesignPage()
        self.createTraitsPage()
        self.createMarketPage()
        self.createOtherPage()
        self.createImagesPage()

    def createStampPage(self):
        self.addTabPage(
            self.tr("Stamp"),
            [
                self.mainDetailsLayout(),
                self.catalogueLayout(),
                self.issueLayout(),
                self.parametersLayout(),
                self.stateLayout(),
                self.urlLayout()
            ]
        )

    def clickEditTags(self):
        dialog = TagsDialog(self.model.database(), self)
        res = dialog.exec_()
        if res == QDialog.Accepted:
            self.tags_item.update()
            self.model.tagsChanged.emit()

        dialog.deleteLater()

    def createImagesPage(self):
        if not self.imagesLayout().isEmpty():
            self.addTabPage(self.tr("Images"), [self.imagesLayout(), ])

    def addItem(self, field):
        checkable = 0
        if self.usedFields:
            checkable = Type.Checkable

        section = None
        if self.reference:
            section = self.reference.section(field.name)

        item = FormItem(
            self.settings,
            field.name,
            field.title,
            field.type | checkable,
            section=section
        )
        if not field.enabled:
            item.setHidden()

        self.items[field.name] = item

    def createItems(self):
        super().createItems()
        if self.reference:
            if self.reference.section('country'):
                country = self.items['country'].widget()
                if self.reference.section('region'):
                    region = self.items['region'].widget()
                    region.addDependent(country)

                if self.reference.section('cancellation'):
                    country.addDependent(self.items['cancellation'].widget())

                if self.reference.section('perforation'):
                    country.addDependent(self.items['perforation'].widget())

                if self.reference.section('printing'):
                    country.addDependent(self.items['printing'].widget())

                if self.reference.section('series'):
                    country.addDependent(self.items['series'].widget())

                if self.reference.section('theme'):
                    country.addDependent(self.items['theme'].widget())

                if self.reference.section('type'):
                    country.addDependent(self.items['type'].widget())

                if self.reference.section('format'):
                    country.addDependent(self.items['format'].widget())

                if self.reference.section('material'):
                    country.addDependent(self.items['material'].widget())

                if self.reference.section('currency'):
                    country.addDependent(self.items['currency'].widget())

            if self.reference.section('material'):
                material = self.items['material'].widget()

                if self.reference.section('material_type'):
                    material_type = self.items['material_type'].widget()
                    material.addDependent(material_type)

                if self.reference.section('thickness'):
                    thickness = self.items['thickness'].widget()
                    material.addDependent(thickness)

        for image_field_src in ImagesFields:
            for image_field_dst in ImagesFields:
                if image_field_dst != image_field_src:
                    if not self.items[image_field_dst].isHidden():
                        src = self.items[image_field_src].widget()
                        dst = self.items[image_field_dst].widget()
                        title = self.items[image_field_dst].title()
                        src.connectExchangeAct(dst, title)

    def fillItems(self, record):
        super().fillItems(record)
        if self.usedFields:
            for item in self.items.values():
                if self.usedFields[record.indexOf(item.field())] == Qt.Checked:
                    item.label().setCheckState(Qt.Checked)

    def mainDetailsLayout(self):
        layout = BaseFormGroupBox(self.tr("Main details"))
        layout.addRow(self.items['region'], self.items['country'])
        btn = QPushButton(self.tr("Generate"))
        btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        btn.clicked.connect(self.clickGenerateTitle)
        layout.addRow(self.items['title'], btn)
        layout.addHalfRow(self.items['denomination'])
        layout.addRow(self.items['year'], self.items['stamp_year'])
        layout.addRow(self.items['type'], self.items['format'])
        layout.addRow(self.items['series'], self.items['theme'])
        return layout

    def parametersLayout(self):
        layout = BaseFormGroupBox(self.tr("Parameters"))
        layout.addRow(self.items['material'], self.items['material_type'])
        layout.addRow(self.items['thickness'], self.items['printing'])
        layout.addRow(self.items['perforation'], self.items['perforation_size'])
        layout.addRow(self.items['full_size'], self.items['picture_size'])
        return layout

    def issueLayout(self):
        layout = BaseFormGroupBox(QApplication.translate('DetailsTabWidget', "Issue"))
        layout.addRow(self.items['issue_date'], self.items['emission_period'])
        layout.addRow(self.items[ 'withdrawal'], self.items['circulation'])
        return layout

    def stateLayout(self):
        layout = BaseFormGroupBox(self.tr("State"))
        layout.addRow(self.items['status'], self.items['quantity'])
        self.items['status'].widget().currentIndexChanged.connect(self.indexChangedState)
        item = QWidget()
        item.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        layout.addRow(self.items['cancellation'], item)
        layout.addRow(self.items['grade'], self.items['condition'])
        layout.addRow(self.items['certificate'])
        layout.addRow(self.items['expert'], self.items['expertise_date'])
        layout.addRow(self.items['rating'])
        return layout

    def payLayout(self):
        layout = BaseFormGroupBox(QApplication.translate('DetailsTabWidget', "Purchase"))
        layout.addRow(self.items['pay_date'], self.items['pay_price'])
        # Add auxiliary field
        if self.items['pay_price'].hidden or self.items['total_pay_price'].hidden:
            item = None
        else:
            item = self.addPayCommission()

        layout.addRow(self.items['total_pay_price'], item)
        layout.addRow(self.items['seller'], self.items['pay_place'])
        layout.addRow(self.items['buying_invoice'])
        layout.addRow(self.items['pay_info'])
        return layout

    def tagsLayout(self):
        self.tags_item = TagsTreeWidget(self.model.database(), False, self)
        return self.tags_item

    def imagesLayout(self):
        layout = ImageFormLayout()
        layout.addRow(self.items['photo1_title'], self.items['photo2_title'])
        layout.addImages([self.items['photo1'], self.items['photo2']])
        layout.addRow(self.items['photo3_title'], self.items['photo4_title'])
        layout.addImages([self.items['photo3'], self.items['photo4']])
        return layout

    def createDesignPage(self):
        self.addTabPage(
            self.tr("Design"),
            [
                self.stampDesignLayout(),
                self.reverseDesignLayout(),
                self.varietyDesignLayout()
            ]
        )

    def createTraitsPage(self):
        self.addTabPage(
            self.tr("Traits"),
            [
                self.watermarkDesignLayout(),
                self.gridDesignLayout(),
                self.honeycombDesignLayout(),
                self.rasterDesignLayout(),
                self.featuresLayout()
            ]
        )

    def clickGenerateTitle(self):
        template = self.settings['title_template']
        title = template
        for field in TitleTemplateFields:
            if '<' + field + '>' in template:
                value = self.items[field].value()
                if not isinstance(value, str):
                    value = str(value)

                value = value.strip()
                if value:
                    if field == 'theme':
                        if len(value.split()) > 1:
                            value = '"' + value + '"'

                title = title.replace('<' + field + '>', value)

        title = re.sub(' +', ' ', title)
        self.items['title'].setValue(title)

    def _createMarketParts(self, status):
        if self.oldStatus in ('owned', 'ordered', 'sale', 'exchange', 'duplicate', 'rarity', 'variety'):
            if self.payCommission:
                self.items['pay_price'].widget().textChanged.disconnect(self.payCommissionChanged)
                self.items['total_pay_price'].widget().textChanged.disconnect(self.payTotalPriceChanged)
                self.payCommission.textChanged.disconnect(self.payCommissionChanged)

            if self.saleCommission:
                self.items['sale_price'].widget().textChanged.disconnect(self.saleCommissionChanged)
                self.items['total_sale_price'].widget().textChanged.disconnect(self.saleTotalPriceChanged)
                self.saleCommission.textChanged.disconnect(self.saleCommissionChanged)
                self.items['sale_price'].widget().textChanged.disconnect(self.items['pay_price'].widget().setText)

            elif self.oldStatus == 'sold':
                if self.payCommission:
                    self.items['pay_price'].widget().textChanged.disconnect(self.payCommissionChanged)
                    self.items['total_pay_price'].widget().textChanged.disconnect(self.payTotalPriceChanged)
                    self.payCommission.textChanged.disconnect(self.payCommissionChanged)

                if self.saleCommission:
                    self.items['sale_price'].widget().textChanged.disconnect(self.saleCommissionChanged)
                    self.items['total_sale_price'].widget().textChanged.disconnect(self.saleTotalPriceChanged)
                    self.saleCommission.textChanged.disconnect(self.saleCommissionChanged)
        else:
            pass

        pageParts = super()._createMarketParts(status)
        self.oldStatus = status
        return pageParts

    def indexChangedState(self, index):
        super().indexChangedState(index)
        if self.oldStatus in ('owned', 'ordered', 'sale', 'exchange', 'duplicate', 'rarity', 'variety'):
            self.payPriceChanged('')

        elif self.oldStatus == 'sold':
            self.payPriceChanged('')
            self.salePriceChanged('')

    def addPayCommission(self):
        item = FormItem(self.settings, None, self.tr("Commission"), Type.Money)
        self.payCommission = item.widget()
        self.payCommission.setToolTip(self.tr("Available format 12.5 or 10%"))

        validator = CommissionValidator(0, 9999999999., 2, self)
        validator.setNotation(QDoubleValidator.StandardNotation)
        self.payCommission.setValidator(validator)

        self.items['pay_price'].widget().textChanged.connect(self.payCommissionChanged)
        self.payCommission.textChanged.connect(self.payCommissionChanged)
        self.items['total_pay_price'].widget().textChanged.connect(self.payTotalPriceChanged)
        return item

    def addSaleCommission(self):
        item = FormItem(self.settings, None, self.tr("Commission"), Type.Money)
        self.saleCommission = item.widget()
        self.saleCommission.setToolTip(self.tr("Available format 12.5 or 10%"))

        validator = CommissionValidator(0, 9999999999., 2, self)
        validator.setNotation(QDoubleValidator.StandardNotation)
        self.saleCommission.setValidator(validator)

        self.items['sale_price'].widget().textChanged.connect(self.saleCommissionChanged)
        self.saleCommission.textChanged.connect(self.saleCommissionChanged)
        self.items['total_sale_price'].widget().textChanged.connect(self.saleTotalPriceChanged)
        return item

    def payCommissionChanged(self, text):
        self.items['total_pay_price'].widget().textChanged.disconnect(self.payTotalPriceChanged)
        price = textToFloat(self.items['pay_price'].value())
        text = self.payCommission.text().strip()
        if len(text) > 0 and text[-1] == '%':
            commission = price * textToFloat(text[0:-1]) / 100
        else:
            commission = textToFloat(text)

        self.items['total_pay_price'].widget().setText(floatToText(price + commission))
        self.items['total_pay_price'].widget().textChanged.connect(self.payTotalPriceChanged)

    def payTotalPriceChanged(self, text):
        self.payCommission.textChanged.disconnect(self.payCommissionChanged)
        if text:
            price = textToFloat(self.items['pay_price'].value())
            totalPrice = textToFloat(self.items['total_pay_price'].value())
            self.payCommission.setText(floatToText(totalPrice - price))
        else:
            self.payCommission.clear()

        self.payCommission.textChanged.connect(self.payCommissionChanged)

    def saleCommissionChanged(self, text):
        self.items['total_sale_price'].widget().textChanged.disconnect(self.saleTotalPriceChanged)
        price = textToFloat(self.items['sale_price'].value())
        text = self.saleCommission.text().strip()
        if len(text) > 0 and text[-1] == '%':
            commission = price * textToFloat(text[0:-1]) / 100
        else:
            commission = textToFloat(text)

        self.items['total_sale_price'].widget().setText(floatToText(price - commission))
        self.items['total_sale_price'].widget().textChanged.connect(self.saleTotalPriceChanged)

    def saleTotalPriceChanged(self, text):
        self.saleCommission.textChanged.disconnect(self.saleCommissionChanged)
        if text:
            price = textToFloat(self.items['sale_price'].value())
            totalPrice = textToFloat(self.items['total_sale_price'].value())
            self.saleCommission.setText(floatToText(price - totalPrice))
        else:
            self.saleCommission.clear()

        self.saleCommission.textChanged.connect(self.saleCommissionChanged)

    def stampDesignLayout(self):
        layout = DesignFormLayout(self.tr("Obverse design"))
        layout.addRow(self.items['designer'], self.items['engraver'])
        layout.addRow(self.items['stamp_design'])
        layout.addRow(self.items['stamp_color1'], self.items['stamp_color2'])
        layout.addImage(self.items['stamp_image'])
        return layout

    def reverseDesignLayout(self):
        layout = DesignFormLayout(self.tr("Gumming"))
        layout.addRow(self.items['stamp_reverse'])
        layout.addRow(self.items['glue'], self.items['glue_color'])
        layout.addImage(self.items['reverse_image'])
        return layout

    def varietyDesignLayout(self):
        layout = DesignFormLayout(self.tr("Variety"))
        layout.layout.columnCount = 4
        item = QWidget()
        item.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        layout.addRow(self.items['variety'], item)
        layout.addRow(self.items['variety_desc'])
        layout.addImage(self.items['variety_image'])
        return layout

    def watermarkDesignLayout(self):
        layout = DesignFormLayout(self.tr("Watermark"))
        layout.addRow(self.items['watermark'], self.items['watermark_image'])
        return layout

    def gridDesignLayout(self):
        layout = DesignFormLayout(self.tr("Grid"))
        layout.addRow(self.items['grid'], self.items['grid_image'])
        return layout

    def honeycombDesignLayout(self):
        layout = DesignFormLayout(self.tr("Honeycomb"))
        layout.addRow(self.items['honeycomb'], self.items['honeycomb_image'])
        return layout

    def rasterDesignLayout(self):
        layout = DesignFormLayout(self.tr("Raster"))
        layout.addRow(self.items['raster'], self.items['raster_image'])
        return layout

    def createOtherPage(self):
        if self.settings['tags_used']:
            btn = QPushButton(self.tr("Edit..."))
            btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
            btn.clicked.connect(self.clickEditTags)

            label = QLabel(self.tr("Tags"))
            label.setAlignment(Qt.AlignCenter)
            label.setStyleSheet("color: blue")

            self.addTabPage(
                QApplication.translate('DetailsTabWidget', "Notes"),
                [
                    self.otherLayout(),
                    label,
                    self.tagsLayout(),
                    btn
                ]
            )
        else:
            self.addTabPage(QApplication.translate('DetailsTabWidget', "Notes"), [self.otherLayout()])

def textToFloat(text):
    if text:
        return stringToMoney(text)
    else:
        return 0


def floatToText(value):
    if value > 0:
        return str(int((value) * 100 + 0.5) / 100)
    else:
        return str(int((value) * 100 - 0.5) / 100)


# Reimplementing DoubleValidator for replace comma with dot and accept %
class CommissionValidator(DoubleValidator):

    def validate(self, input_, pos):
        hasPercent = False
        numericValue = input_
        if len(input_) > 0 and input_[-1] == '%':
            numericValue = input_[0:-1]  # trim percent sign
            hasPercent = True

        state, validatedValue, pos = super().validate(numericValue, pos)
        if hasPercent:
            validatedValue = validatedValue + '%'  # restore percent sign

        return state, validatedValue, pos
